package com.kly.user.eventbus;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.common.utils.HttpUtil;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Maps;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.DeadEvent;
import com.google.common.eventbus.Subscribe;
import com.kly.enums.ParameterTypeEnum;
import com.kly.user.db.dao.*;
import com.kly.user.db.entity.*;
import com.kly.user.enums.AppEnum;
import com.kly.user.msgClient.MsgAPI;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * EventBus 监听器
 * @author linqu
 */
@Component
public class EventListener {

    private static Log logger = LogFactory.getLog(EventListener.class);

    @Resource
    AsyncEventBus asyncEventBus;
    @Resource
    MsgAPI msgAPI;
    @Resource
    UserBehaviorLogDao userBehaviorLogDao;
    @Resource
    UserPreHomepageDao userPreHomepageDao;
    @Resource
    UserMsgSendTotalDao userMsgSendTotalDao;
    @Resource
    UserMsgSendPreDayDao userMsgSendPreDayDao;
    @Resource
    UserChatterMappingDao userChatterMappingDao;
    @NacosValue(value = "${chatter.url:http://localhost:9105/api/chat/sendMessageNotice}")
    private String chatterApiUrl;
    /**
     * 订阅者注册到EventBus
     */
    @PostConstruct
    public void init() {
        asyncEventBus.register(this);
    }

    /**
     * 接收到指定事件后的处理
     * @param event
     */
    @Subscribe
    public void pushMsg(Event event) {
        logger.info("pushMsgStart: {}", JSONObject.toJSONString(event));
        try {
            final ActionEnum eventTypeEnum = event.getEventActionEnum();
            if (eventTypeEnum.equals(ActionEnum.PUSH_MSG)) {
                final String content = event.getContent();
                final JSONObject contentJson = JSONObject.parseObject(content);
                final Integer type = contentJson.getInteger("type");
                // mechat消息通知：matched 列表消息
                if (ParameterTypeEnum.MATCHED_PUSH.getId().equals(type)) {
                    msgAPI.postMatchedRequest(event.getApp(), event.getToUserCode(), event, type);
                }
                // meboo消息通知：消息回复
                else if (ParameterTypeEnum.MESSAGE_FEEDBACK.getId().equals(type)
                        || ParameterTypeEnum.NORMAL_IMAGE.getId().equals(type)
                        || ParameterTypeEnum.PRIVATE_IMAGE.getId().equals(type)
                        || ParameterTypeEnum.NORMAL_VIDEO.getId().equals(type)
                        || ParameterTypeEnum.PRIVATE_VIDEO.getId().equals(type) ) {
                    if (AppEnum.MEBOO.equals(event.getApp())) {
                        msgAPI.postMessageFeedbackRequest(event.getApp(), event.getToUserCode(), type, event);
                    } else if (AppEnum.MECHAT.equals(event.getApp())) {
                        msgAPI.postMessageToMeChat(event.getApp(), event.getToUserCode(), type, event, contentJson);
                    }
                }
                // remind消息推送
                else if (ParameterTypeEnum.PUSH_REMIND.getId().equals(type)) {
                    msgAPI.postRemindMessage(event.getApp(), event.getToUserCode(), event);
                }
                // meboo WhoLikesMe消息通知
                else if (ParameterTypeEnum.WHO_LIKE_ME.getId().equals(type)) {
                    /**
                     * 推送消息到MEBOO
                     */
                    msgAPI.postMessageWhoLikeMeRequest(event.getApp(), event.getToUserCode(), event, type);
                    /**
                     * 推送通知状态，通知wlm列表UI进行刷新
                     */
//                    msgAPI.postMessageWhoLikeMeRequest2(event.getApp(), event.getToUserCode(), event, type);
                }
                // 举报消息通知
                else if (ParameterTypeEnum.REPORT.getId().equals(type)) {
                    msgAPI.postRequestMessageRequest(event.getApp(), event.getToUserCode(), event, type);
                }
                // 头像修改
                else if (ParameterTypeEnum.AVATAR_CHANGE.getId().equals(type)) {
                    /**
                     * 推送通知状态，通知wlm列表UI进行刷新
                     */
                    msgAPI.postMessageAvatarChange(event.getApp(), event.getFromUserCode(), event.getToUserCode(), event, type);
                }

                // 推送model在线状态
                else if (ParameterTypeEnum.PUSH_MODEL_ONLINE.getId().equals(type)) {
                    final String target = contentJson.getString("target");
                    final Integer online = contentJson.getInteger("online");
                    final Integer userType = contentJson.getInteger("userType");
                    final Integer flashchatFlag = contentJson.getInteger("flashchatFlag");
                    final String modelUserCode = contentJson.getString("modelUserCode");
                    msgAPI.postModelOnlineStatusToUser(event.getApp(), event.getFromUserCode(), event.getToUserCode(), event, userType, target, online, flashchatFlag, modelUserCode);
                }
                // 发送会员等级
                else if (ParameterTypeEnum.PUSH_CHAT_LEVEL.getId().equals(type)) {
                    msgAPI.postChatLevelToMeChat(AppEnum.MECHAT, event, contentJson);
                }



            } else if (eventTypeEnum.equals(ActionEnum.LOG)) {
                UserBehaviorLogEntity logEntity = new UserBehaviorLogEntity();
                JSONObject contentJson = JSONObject.parseObject(event.getContent());
                logEntity.setUserCode(event.getFromUserCode());
                logEntity.setActionType(contentJson.getInteger("actionType"));
                logEntity.setActionName(contentJson.getString("actionName"));
                logEntity.setUserCodeOperated(event.getToUserCode());
                userBehaviorLogDao.insert(logEntity);
            }
            // 首页数据缓存
            else if (eventTypeEnum.equals(ActionEnum.STORE_PRE_HOME_DATA)) {
                final String content = event.getContent();
                if (StringUtils.isEmpty(content)) {
                    return;
                }
                final List<UserPreHomepageEntity> userPreHomepageEntities = JSONObject.parseArray(content, UserPreHomepageEntity.class);
                userPreHomepageEntities.parallelStream().forEach(o -> {
                    final UserPreHomepageEntity entity = userPreHomepageDao.queryByUserCode(o.getUserCode(), o.getUserCodeWlm());
                    if (Objects.nonNull(entity)) {
                        return;
                    }
                    userPreHomepageDao.insert(o);
                });
            }

            // 用户发送消息数
            else if (eventTypeEnum.equals(ActionEnum.STORE_MSG_DATA)) {

                // 用户发送消息总数汇总
                final List<UserMsgSendTotalEntity> userMsgSendTotalEntities = userMsgSendTotalDao.queryByUserCode(event.getFromUserCode(), event.getToUserCode());
                if (CollectionUtils.isEmpty(userMsgSendTotalEntities)) {
                    UserMsgSendTotalEntity entity = new UserMsgSendTotalEntity();
                    entity.setFromUserCode(event.getFromUserCode());
                    entity.setToUserCode(event.getToUserCode());
                    entity.setMsgNum(1);
                    userMsgSendTotalDao.insert(entity);
                } else {
                    final UserMsgSendTotalEntity existsRecords = userMsgSendTotalEntities.get(0);
                    existsRecords.setMsgNum(existsRecords.getMsgNum() + 1);
                    userMsgSendTotalDao.updateByPrimaryKey(existsRecords);
                }

                // 当日发送消息数汇总
                final String today = DateUtil.getDate("yyyyMMdd");
                UserMsgSendPreDayEntity todayRecord = userMsgSendPreDayDao.getUserMsgSendPreDay(Integer.valueOf(today), event.getFromUserCode(), event.getToUserCode());
                final String chatterUserCode = getChatterUserCode(event);
                if (todayRecord == null) {
                    todayRecord = new UserMsgSendPreDayEntity();
                    todayRecord.setSendDate(Integer.valueOf(today));
                    todayRecord.setChatterUserCode(chatterUserCode);
                    todayRecord.setFromUserCode(event.getFromUserCode());
                    todayRecord.setToUserCode(event.getToUserCode());
                    todayRecord.setMsgNum(1);
                    userMsgSendPreDayDao.insert(todayRecord);
                } else {
                    todayRecord.setMsgNum(todayRecord.getMsgNum() + 1);
                    userMsgSendPreDayDao.updateByPrimaryKey(todayRecord);
                }

                // 发送当日消息数到mechat
                Map<String, String> header = Maps.newHashMap();
                header.put("Content-Type", "application/json");

                Map<String, Object> params = Maps.newHashMap();
                params.put("userCode", event.getFromUserCode());
                params.put("modelUserCode", event.getToUserCode());
                params.put("messageCount", todayRecord.getMsgNum());
                params.put("chatterCode", todayRecord.getChatterUserCode());
                final String response = HttpUtil.postPageBody(chatterApiUrl, header, JSONObject.toJSONString(params));
                logger.info("用户发送消息数, req:{}, res:{}", JSONObject.toJSONString(params), response);

            }

        } catch (Exception e) {
            logger.error("pushMsgError: {}", JSONObject.toJSONString(event), e);
        }
        logger.info("pushMsgEnd: {}", JSONObject.toJSONString(event));
    }

    private String getChatterUserCode(Event event) {
        String chatterUserCode = JSONObject.parseObject(event.getContent()).getString("chatterUserCode");
        if (StringUtils.isEmpty(chatterUserCode)) {
            final List<UserChatterMappingEntity> userChatterMapping = userChatterMappingDao.queryByModelUserCode(event.getToUserCode());
            if (!CollectionUtils.isEmpty(userChatterMapping)) {
                chatterUserCode = userChatterMapping.get(0).getChatterUserCode();
            }
        }
        return chatterUserCode;
    }

    /**
     * 接收没有订阅者的消息
     * @param event
     */
    @Subscribe
    public void handle(DeadEvent event){
        // 事件无法处理, 只记录日志
        logger.error("The event un-subscribe yet, event ：{}",event);
    }
}